package com.lct.simpleforecast.delegates

import android.content.Context
import android.content.SharedPreferences
import com.lct.simpleforecast.MyApplication
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

/**
 * Author：SkySmile
 * Date：2018/7/4
 * Description：自定义委托
 */
object DelegatesExt {
    /**
     * 属性只能被初始化一次
     */
    fun <T> notNullSingleValue(): ReadWriteProperty<Any?, T> = NotNullSingleValueVar()

    /**
     * SharedPreferences委托
     */
    fun <T : Any> preference(key: String, default: T): ReadWriteProperty<Any?, T> =
            Preference(key, default)
}

private class NotNullSingleValueVar<T> : ReadWriteProperty<Any?, T> {
    private var value: T? = null

    override fun getValue(thisRef: Any?, property: KProperty<*>): T {
        return value ?: throw IllegalStateException("${property.name} not initialized")
    }

    override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        this.value =
                if (this.value == null) value
                else throw IllegalStateException("${property.name} already initialized")
    }
}

private class Preference<T>(val key: String, val default: T) : ReadWriteProperty<Any?, T> {
    val prefs: SharedPreferences by lazy {
        MyApplication.instance.getSharedPreferences("config", Context.MODE_PRIVATE)
    }

    override fun getValue(thisRef: Any?, property: KProperty<*>): T {
        with(prefs) {
            val value: Any = when (default) {
                is Int -> getInt(key, default)
                is Long -> getLong(key, default)
                is Float -> getFloat(key, default)
                is Boolean -> getBoolean(key, default)
                is String -> getString(key, default)
                else -> throw IllegalArgumentException("This type can't be saved into Preferences")
            }
            @Suppress("UNCHECKED_CAST")
            return value as T
        }
    }

    override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        val editor = prefs.edit()
        with(editor) {
            when (default) {
                is Int -> putInt(key, value as Int)
                is Long -> putLong(key, value as Long)
                is Float -> putFloat(key, value as Float)
                is Boolean -> putBoolean(key, value as Boolean)
                is String -> putString(key, value as String)
                else -> throw IllegalArgumentException("This type can't be saved into Preferences")
            }.apply()
        }
    }
}